package com.bgds.sys.data.iXCom29d.gateway.impl;

import com.cisdi.data.common.exception.BusinessException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;

/**
 * @author
 * 编码
 */
public class BaoXingVoEncoder extends MessageToByteEncoder<BaoXingVo> {
	
	private static final Logger logger = LoggerFactory.getLogger(BaoXingVoEncoder.class);

	private Object lockObj = new Object();

	private Charset charset;
	
	public BaoXingVoEncoder(Charset charset) {
		this.charset = charset;
	}
	
	@Override
	protected void encode(ChannelHandlerContext ctx, BaoXingVo msg, ByteBuf out) throws Exception {
		try {
			byte[] bodyBytes = getBodyBtyes(msg, charset);
		   synchronized (lockObj) {
			    out.writeBytes(bodyBytes);
			   // 1 个字节的结束符
			   out.writeByte(BaoXingConsts.MSG_END_BYTE);
		   }
		} catch (Exception e) {
			logger.warn("编码消息发生异常" + e.getMessage(), e);
			throw e;
		}
	}
	public static byte[] getBodyBtyes(BaoXingVo msg, Charset charset) {
		if(msg == null) {
			throw new BusinessException("encode BaoXingVo is null");
		}
		if(msg.getBody() != null && msg.getBody().length() > BaoXingConsts.MAX_DATA_BODY_LENGTH) {
			throw new BusinessException("超过允许的最大电文changdu:" + BaoXingConsts.MAX_DATA_BODY_LENGTH);
		}
		// length 不用检测，自动计算生成
		// 判断msg格式是否正确
		//checkParam(msg.getMsgKey(), 23, false, "msgKey");
		checkParam(msg.getMsgKey(), 6, false, "msgKey");
		checkParam(msg.getDate(), 8, true, "date");
		checkParam(msg.getTime(), 6, true, "time");
//		checkParam(msg.getSendDc(), 2, false, "sendDc");
//		checkParam(msg.getReceiveDc(), 2, false, "receiveDc");
//		checkParam(msg.getFuncCode(), 1, false, "reserved");
        StringBuilder builder = new StringBuilder();
        builder.append(msg.getMsgKey());
        builder.append(msg.getDate());
        builder.append(msg.getTime());
//        builder.append(msg.getSendDc());
//        builder.append(msg.getReceiveDc());
        builder.append(msg.getFuncCode());
        //判断body是否为空
        if(msg.getBody() != null){
		   builder.append(msg.getBody());
        }
        int totalLength = builder.toString().getBytes(charset).length + 1 + 4;
        builder.insert(0, String.format("%04d", totalLength));
        String headerWithBody = builder.toString();
        byte[] bodyBytes = headerWithBody.getBytes(charset);
		return bodyBytes;
	}

	private static void checkParam(Object value, int requireLength, boolean isInteger, String name) {
		if(value == null) {
			throw new BusinessException( String.valueOf(name) + " is null");
		}
		
		String string = String.valueOf(value);
		
		if(string.length() != requireLength) {
			throw new BusinessException(String.valueOf(name) + " length 必须为" + requireLength );
		}
		if(isInteger) {
			try {
				Integer valueOf = Integer.valueOf(string);
				
				if(valueOf > Math.pow(10, requireLength + 1)) {
					throw new BusinessException(String.valueOf(name) + "超出了允许的范围，最大长度为" + requireLength);
				}
			} catch (Exception e) {
				throw new BusinessException(String.valueOf(name) + "必须为数字 ");
			}
		}		
	}
}